﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace PhoneAppCheckSensors
{
    using Microsoft.Devices.Sensors;
    using Microsoft.Xna.Framework;

    public partial class PageGyroscope : PhoneApplicationPage
    {
        public PageGyroscope()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (mySensor == null)
            {
                mySensor = new Gyroscope();
                mySensor.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<GyroscopeReading>>(mySensor_CurrentValueChanged);
            }

            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (buttonStop.IsEnabled)
            {
                mySensor.Stop();
                buttonStart.IsEnabled = true;
                buttonStop.IsEnabled = false;
                buttonDraw.IsEnabled = false;
            }

            base.OnNavigatedFrom(e);
        }

        private Gyroscope mySensor;
        private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            gpX.AdjustDrawArea();
            gpY.AdjustDrawArea();
            gpZ.AdjustDrawArea();

            buttonStart.IsEnabled = false;
            buttonStop.IsEnabled = true;
            mySensor.Start();
            buttonDraw.IsEnabled = true;

            foreach (var item in ApplicationBar.Buttons)
            {
                var button = item as Microsoft.Phone.Shell.ApplicationBarIconButton;
                button.IsEnabled = false;
            }
        }

        void mySensor_CurrentValueChanged(object sender, SensorReadingEventArgs<GyroscopeReading> e)
        {
            Dispatcher.BeginInvoke(()=>{
                tbTimestamp.Text = e.SensorReading.Timestamp.ToString();

                float rrX = e.SensorReading.RotationRate.X;
                float rrY = e.SensorReading.RotationRate.Y;
                float rrZ = e.SensorReading.RotationRate.Z;

                tbRRX.Text = String.Format("{0:0.0000}", rrX);
                tbRRY.Text = String.Format("{0:0.0000}", rrY);
                tbRRZ.Text = String.Format("{0:0.0000}", rrZ);

                gpX.AddPoint(e.SensorReading.Timestamp, rrX);
                gpY.AddPoint(e.SensorReading.Timestamp, rrY);
                gpZ.AddPoint(e.SensorReading.Timestamp, rrZ);

                measuredGyros.Add(new MeasuredGyroData()
                {
                    MeasuredTime = e.SensorReading.Timestamp.Ticks.ToString(),
                    X = e.SensorReading.RotationRate.X,
                    Y = e.SensorReading.RotationRate.Y,
                    Z = e.SensorReading.RotationRate.Z
                });
            });
        }

        private void buttonStop_Click(object sender, RoutedEventArgs e)
        {
            buttonStart.IsEnabled = true;
            buttonStop.IsEnabled = false;

            foreach (var item in ApplicationBar.Buttons)
            {
                var button = item as Microsoft.Phone.Shell.ApplicationBarIconButton;
                button.IsEnabled = true;
            }

            mySensor.Stop();
        }

        private void buttonDraw_Click(object sender, RoutedEventArgs e)
        {
            gpX.DrawGraph();
            gpY.DrawGraph();
            gpZ.DrawGraph();
        }

        List<MeasuredGyroData> measuredGyros = new List<MeasuredGyroData>();
        private const string sensorTypeName = "Gyroscope";
        private const int maxStoredDataNo = 1000;

        private string SaveDataToFile()
        {
            var fileStorage = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
            string path = sensorTypeName + DateTime.Now.ToString("yyyymmdd_hhMMss") + ".xml";
            var builder = new System.Text.StringBuilder();
            using (var stream = new System.IO.IsolatedStorage.IsolatedStorageFileStream(path, System.IO.FileMode.CreateNew, fileStorage))
            {
                builder.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
                builder.Append("<" + sensorTypeName + ">");
                foreach (var md in measuredGyros)
                {
                    builder.Append("<seg time=\"" + md.MeasuredTime + "\">");
                    builder.AppendFormat("<X>{0}</X>", md.X);
                    builder.AppendFormat("<Y>{0}</Y>", md.Y);
                    builder.AppendFormat("<Z>{0}</Z>", md.Z);
                    builder.Append("</seg>");
                }
                builder.Append("</" + sensorTypeName + ">");
                var twriter = new System.IO.StreamWriter(stream);
                twriter.WriteLine(builder.ToString());
            }
            return path;
        }

        private void ApplicationBarIconButtonSave_Click(object sender, EventArgs e)
        {
            string path = SaveDataToFile();
            NavigationService.Navigate(new Uri("/PageSaveToSkyDrive.xaml?NavigatedFrom=sensor&sensortype=" + sensorTypeName + "&datafile=" + path, UriKind.Relative));

            foreach (var item in ApplicationBar.Buttons)
            {
                var button = item as Microsoft.Phone.Shell.ApplicationBarIconButton;
                button.IsEnabled = false;
            }
        }

        private void ApplicationBarIconButtonSend_Click(object sender, EventArgs e)
        {
            string path = SaveDataToFile();
            NavigationService.Navigate(new Uri("/PageSendData.xaml?NavigatedFrom=sensor&sensortype=" + sensorTypeName + "&datafile=" + path, UriKind.Relative));

            foreach (var item in ApplicationBar.Buttons)
            {
                var button = item as Microsoft.Phone.Shell.ApplicationBarIconButton;
                button.IsEnabled = false;
            }
        }
    }

    struct MeasuredGyroData
    {
        public string MeasuredTime;
        public float X;
        public float Y;
        public float Z;
    }
}